# liberías habituales
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy as scipy
from scipy import stats
# librerías especializadas en análisis geoespacial
import pysal as ps
import geopandas as gpd
import cartopy
import cartopy.crs as ccrs
import skgstat as skg
import seaborn as sns
import mapclassify
# ignorar warnings
from numba.core.errors import NumbaDeprecationWarning, NumbaPendingDeprecationWarning
import warnings
warnings.simplefilter('ignore', category=NumbaDeprecationWarning)
warnings.simplefilter('ignore', category=FutureWarning)
Cargamos los datos y creamos un dataframe. A su vez, limpiamos los datos para trabajar más cómodamente.
j23 = gpd.read_file('Elecciones.csv')
# Lista de partidos (vamos a cambiarles el tipo de dato)
columnas_partidos = ['PP', 'PSOE', 'VOX', 'SUMAR', 'ERC', 'JxCAT - JUNTS', 'EH Bildu', 'EAJ-PNV', 'B.N.G.',
'CCa', 'U.P.N.', 'PACMA', 'CUP-PR', 'FO', 'NC-bc', 'PDeCAT-E-CiU', 'RECORTES CERO',
'PUM+J', 'U.P.L.', 'EXISTE', 'PCTE', 'GBAI', 'SY', 'ADELANTE ANDALUCÍA', 'ESCAÑOS EN BLANCO',
'JM+', 'XAV', 'BQEX', 'CJ', 'FE de las JONS', 'PAR', 'ESPAÑA VACIADA', 'PH', 'ASTURIAS EXISTE EV',
'XH', 'VP', 'Zsi', 'VB', 'POR MI REGIÓN', 'AHORA CANARIAS-PCPC', 'PARTIDO AUTÓNOMOS', 'EVB',
'CpM', 'JxG', 'EV-PCAS-TC', 'PREPAL', 'Somos Cc', 'ALM', 'F.I.A.', '3e', 'Ud.Ca', 'GITV',
'PUEDE', 'EVC', 'LB', 'UNIDOS SI', '+RDS+', 'CCD', 'FUERZA CÍVICA']
# Iteramos sobre las columnas y convertimos a numérico
for columna in columnas_partidos:
j23[columna] = j23[columna].str.replace('.', '').astype(int)
# Visualizamos el DataFrame actualizado
#print(j23.head())
j23['Código de Municipio'] = j23['Código de Municipio'].astype(str)
j23['Código de Municipio'] = j23['Código de Municipio'].str.zfill(3)
j23['Código de Provincia'] = j23['Código de Provincia'].astype(str)
j23['Código de Provincia'] = j23['Código de Provincia'].str.zfill(2)
#j23.info()
# Trabajaremos sólo con datos en la Península
j23 = j23[~j23['Nombre de Provincia'].str.contains('Las Palmas|Santa Cruz de Tenerife|Ceuta|Illes Balears|Melilla')]
j23
| Nombre de Comunidad | Código de Provincia | Nombre de Provincia | Código de Municipio | Nombre de Municipio | Población | Número de mesas | Total censo electoral | Total votantes | Votos válidos | ... | Ud.Ca | GITV | PUEDE | EVC | LB | UNIDOS SI | +RDS+ | CCD | FUERZA CÍVICA | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Andalucía | 04 | Almería | 001 | Abla | 1.247 | 2 | 995 | 747 | 741 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | None |
| 1 | Andalucía | 04 | Almería | 002 | Abrucena | 1.221 | 2 | 1.034 | 787 | 781 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | None |
| 2 | Andalucía | 04 | Almería | 003 | Adra | 25.300 | 29 | 17.557 | 11.748 | 11.623 | ... | 0 | 0 | 0 | 0 | 5 | 0 | 0 | 0 | 0 | None |
| 3 | Andalucía | 04 | Almería | 004 | Albanchez | 735 | 1 | 387 | 293 | 291 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | None |
| 4 | Andalucía | 04 | Almería | 005 | Alboloduy | 615 | 1 | 504 | 397 | 397 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | None |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 8124 | Comunitat Valenciana | 46 | Valencia / València | 262 | La Yesa | 227 | 1 | 206 | 171 | 169 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | None |
| 8125 | Comunitat Valenciana | 46 | Valencia / València | 263 | Zarra | 370 | 1 | 250 | 194 | 189 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | None |
| 8126 | Comunitat Valenciana | 46 | Valencia / València | 902 | Gátova | 412 | 1 | 373 | 318 | 310 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | None |
| 8127 | Comunitat Valenciana | 46 | Valencia / València | 903 | San Antonio de Benagéber | 9.874 | 10 | 6.934 | 5.454 | 5.414 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | None |
| 8128 | Comunitat Valenciana | 46 | Valencia / València | 904 | Benicull de Xúquer | 1.102 | 1 | 894 | 688 | 679 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | None |
7974 rows × 73 columns
# Convertimos la columna 'Total votantes' a tipo numérico
j23['Total votantes'] = pd.to_numeric(j23['Total votantes'], errors='coerce')
# Agrupamos por provincia y sumamos el total de votantes
suma_votantes_por_provincia = j23.groupby('Nombre de Provincia')['Total votantes'].sum().reset_index()
# Mostramos la tabla resultante
print(suma_votantes_por_provincia)
Nombre de Provincia Total votantes 0 A Coruña 8719.730 1 Albacete 24419.836 2 Alicante / Alacant 21848.416 3 Almería 22529.194 4 Araba / Álava 16943.650 5 Asturias 17757.237 6 Badajoz 45266.806 7 Barcelona 39673.243 8 Bizkaia 26755.178 9 Burgos 53513.376 10 Cantabria 19489.541 11 Castellón / Castelló 29741.673 12 Ciudad Real 27788.413 13 Cuenca 41594.389 14 Cáceres 69200.180 15 Cádiz 3554.018 16 Córdoba 14484.387 17 Gipuzkoa 17280.705 18 Girona 49878.221 19 Granada 43568.723 20 Guadalajara 27394.707 21 Huelva 13378.041 22 Huesca 42706.561 23 Jaén 15736.717 24 La Rioja 23829.780 25 León 57820.138 26 Lleida 54302.999 27 Lugo 13145.011 28 Madrid 25606.774 29 Murcia 4178.281 30 Málaga 23262.450 31 Navarra 47766.812 32 Ourense 37401.959 33 Palencia 26618.761 34 Pontevedra 2744.118 35 Salamanca 60058.977 36 Segovia 32953.484 37 Sevilla 9584.913 38 Soria 15008.506 39 Tarragona 37865.901 40 Teruel 31865.297 41 Toledo 43269.546 42 Valencia / València 56473.583 43 Valladolid 36772.655 44 Zamora 49590.388 45 Zaragoza 52132.674 46 Ávila 34510.790
Cargamos un shapefile con la geometría de los municipios de España. Fuente: https://centrodedescargas.cnig.es/CentroDescargas/index.jsp
muni_shp = gpd.read_file('recintos_municipales_inspire_peninbal_etrs89/recintos_municipales_inspire_peninbal_etrs89.shp')
# Cambiamos el sistema de coordenadas y proyección
muni_shp.crs = {'init' :'epsg:25830'}
#muni_shp
Al igual que con nuestro dataframe de las elecciones, eliminamos todos los territorios que se encuentren fuera de la península
# Extraer el código del municipio (tres dígitos)
muni_shp['MUNI_CODE'] = muni_shp['NATCODE'].str.extract(r'(\d{3})$')
# Extraer el código de la provincia (dos dígitos)
muni_shp['PROV_CODE'] = muni_shp['NATCODE'].str.extract(r'(\d{2})\d{3}$')
muni_shp = muni_shp[muni_shp['PROV_CODE'].str.contains('07|51|52|35|38|53|54') == False]
# Visualizar el GeoDataFrame actualizado
muni_shp
| INSPIREID | COUNTRY | NATLEV | NATLEVNAME | NATCODE | NAMEUNIT | CODNUT1 | CODNUT2 | CODNUT3 | geometry | MUNI_CODE | PROV_CODE | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ES.IGN.BDDAE.34010404001 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34010404001 | Abla | ES6 | ES61 | ES611 | POLYGON ((-2.785 37.093, -2.784 37.095, -2.784... | 001 | 04 |
| 1 | ES.IGN.BDDAE.34010404002 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34010404002 | Abrucena | ES6 | ES61 | ES611 | POLYGON ((-2.890 37.092, -2.890 37.092, -2.889... | 002 | 04 |
| 2 | ES.IGN.BDDAE.34010404003 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34010404003 | Adra | ES6 | ES61 | ES611 | POLYGON ((-3.140 36.788, -3.140 36.788, -3.139... | 003 | 04 |
| 3 | ES.IGN.BDDAE.34010404004 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34010404004 | Albanchez | ES6 | ES61 | ES611 | POLYGON ((-2.202 37.312, -2.202 37.312, -2.201... | 004 | 04 |
| 4 | ES.IGN.BDDAE.34010404005 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34010404005 | Alboloduy | ES6 | ES61 | ES611 | POLYGON ((-2.713 37.078, -2.711 37.080, -2.711... | 005 | 04 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 8116 | ES.IGN.BDDAE.34172626179 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34172626179 | Viniegra de Arriba | ES2 | ES23 | ES230 | POLYGON ((-2.852 42.119, -2.848 42.115, -2.845... | 179 | 26 |
| 8117 | ES.IGN.BDDAE.34172626178 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34172626178 | Viniegra de Abajo | ES2 | ES23 | ES230 | POLYGON ((-2.920 42.224, -2.919 42.224, -2.916... | 178 | 26 |
| 8118 | ES.IGN.BDDAE.34172626180 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34172626180 | Zarratón | ES2 | ES23 | ES230 | POLYGON ((-2.916 42.528, -2.914 42.528, -2.913... | 180 | 26 |
| 8119 | ES.IGN.BDDAE.34172626181 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34172626181 | Zarzosa | ES2 | ES23 | ES230 | POLYGON ((-2.402 42.146, -2.401 42.154, -2.398... | 181 | 26 |
| 8120 | ES.IGN.BDDAE.34172626183 | ES | https://inspire.ec.europa.eu/codelist/Administ... | Municipio | 34172626183 | Zorraquín | ES2 | ES23 | ES230 | POLYGON ((-3.060 42.338, -3.042 42.337, -3.036... | 183 | 26 |
7974 rows × 12 columns
Ahora, el número de filas coinciden en ambos, j23 y muni_shp, por lo que podemos fusionar los dos dataframes
UNIMOS "j23" (Elecciones) CON "muni_shp" (Municipios Shape)¶
elecciones = gpd.GeoDataFrame(pd.merge(j23, muni_shp, left_on=['Código de Provincia', 'Código de Municipio'], right_on=['PROV_CODE', 'MUNI_CODE'], how='left'))
#elecciones.head()
# dropeamos columna geometry para limpiar
elecciones = elecciones.drop(columns=['geometry_x']) # Eliminar la columna 'geometry_x'
elecciones = elecciones.rename(columns={'geometry_y': 'geometry'}) # Renombrar 'geometry_y' a 'geometry'
#sistema de coordenadas y proyección
elecciones.crs = {'init' :'epsg:25830'} #otra forma de hacerlo es con df.set_geometry('geometry', crs='epsg:25830')
elecciones.info()
<class 'geopandas.geodataframe.GeoDataFrame'> RangeIndex: 7974 entries, 0 to 7973 Data columns (total 84 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Nombre de Comunidad 7974 non-null object 1 Código de Provincia 7974 non-null object 2 Nombre de Provincia 7974 non-null object 3 Código de Municipio 7974 non-null object 4 Nombre de Municipio 7974 non-null object 5 Población 7974 non-null object 6 Número de mesas 7974 non-null object 7 Total censo electoral 7974 non-null object 8 Total votantes 7973 non-null float64 9 Votos válidos 7974 non-null object 10 Votos a candidaturas 7974 non-null object 11 Votos en blanco 7974 non-null object 12 Votos nulos 7974 non-null object 13 PP 7974 non-null int64 14 PSOE 7974 non-null int64 15 VOX 7974 non-null int64 16 SUMAR 7974 non-null int64 17 ERC 7974 non-null int64 18 JxCAT - JUNTS 7974 non-null int64 19 EH Bildu 7974 non-null int64 20 EAJ-PNV 7974 non-null int64 21 B.N.G. 7974 non-null int64 22 CCa 7974 non-null int64 23 U.P.N. 7974 non-null int64 24 PACMA 7974 non-null int64 25 CUP-PR 7974 non-null int64 26 FO 7974 non-null int64 27 NC-bc 7974 non-null int64 28 PDeCAT-E-CiU 7974 non-null int64 29 RECORTES CERO 7974 non-null int64 30 PUM+J 7974 non-null int64 31 U.P.L. 7974 non-null int64 32 EXISTE 7974 non-null int64 33 PCTE 7974 non-null int64 34 GBAI 7974 non-null int64 35 SY 7974 non-null int64 36 ADELANTE ANDALUCÍA 7974 non-null int64 37 ESCAÑOS EN BLANCO 7974 non-null int64 38 JM+ 7974 non-null int64 39 XAV 7974 non-null int64 40 BQEX 7974 non-null int64 41 CJ 7974 non-null int64 42 FE de las JONS 7974 non-null int64 43 PAR 7974 non-null int64 44 ESPAÑA VACIADA 7974 non-null int64 45 PH 7974 non-null int64 46 ASTURIAS EXISTE EV 7974 non-null int64 47 XH 7974 non-null int64 48 VP 7974 non-null int64 49 Zsi 7974 non-null int64 50 VB 7974 non-null int64 51 POR MI REGIÓN 7974 non-null int64 52 AHORA CANARIAS-PCPC 7974 non-null int64 53 PARTIDO AUTÓNOMOS 7974 non-null int64 54 EVB 7974 non-null int64 55 CpM 7974 non-null int64 56 JxG 7974 non-null int64 57 EV-PCAS-TC 7974 non-null int64 58 PREPAL 7974 non-null int64 59 Somos Cc 7974 non-null int64 60 ALM 7974 non-null int64 61 F.I.A. 7974 non-null int64 62 3e 7974 non-null int64 63 Ud.Ca 7974 non-null int64 64 GITV 7974 non-null int64 65 PUEDE 7974 non-null int64 66 EVC 7974 non-null int64 67 LB 7974 non-null int64 68 UNIDOS SI 7974 non-null int64 69 +RDS+ 7974 non-null int64 70 CCD 7974 non-null int64 71 FUERZA CÍVICA 7974 non-null int64 72 INSPIREID 7974 non-null object 73 COUNTRY 7974 non-null object 74 NATLEV 7974 non-null object 75 NATLEVNAME 7974 non-null object 76 NATCODE 7974 non-null object 77 NAMEUNIT 7974 non-null object 78 CODNUT1 7974 non-null object 79 CODNUT2 7974 non-null object 80 CODNUT3 7974 non-null object 81 geometry 7974 non-null geometry 82 MUNI_CODE 7974 non-null object 83 PROV_CODE 7974 non-null object dtypes: float64(1), geometry(1), int64(59), object(23) memory usage: 5.1+ MB
Creamos Columna: Partido mas votado
columnas_votos = ['PP', 'PSOE', 'VOX', 'SUMAR', 'ERC', 'JxCAT - JUNTS', 'EH Bildu', 'EAJ-PNV', 'B.N.G.', 'CCa', 'U.P.N.', 'PACMA', 'CUP-PR', 'FO', 'NC-bc', 'PDeCAT-E-CiU', 'RECORTES CERO', 'PUM+J', 'U.P.L.', 'EXISTE', 'PCTE', 'GBAI', 'SY', 'ADELANTE ANDALUCÍA', 'ESCAÑOS EN BLANCO', 'JM+', 'XAV', 'BQEX', 'CJ', 'FE de las JONS', 'PAR', 'ESPAÑA VACIADA', 'PH', 'ASTURIAS EXISTE EV', 'XH', 'VP', 'Zsi', 'VB', 'POR MI REGIÓN', 'AHORA CANARIAS-PCPC', 'PARTIDO AUTÓNOMOS', 'EVB', 'CpM', 'JxG', 'EV-PCAS-TC', 'PREPAL', 'Somos Cc', 'ALM', 'F.I.A.', '3e', 'Ud.Ca', 'GITV', 'PUEDE', 'EVC', 'LB', 'UNIDOS SI', '+RDS+', 'CCD', 'FUERZA CÍVICA']
# Convertimos columnas de votos a tipo numérico
elecciones[columnas_votos] = elecciones[columnas_votos].apply(pd.to_numeric, errors='coerce')
# Creamos columna del partido más votado
elecciones['Partido_Mas_Votado'] = elecciones[columnas_votos].idxmax(axis=1)
# Creamos la columna de votos al partido más votado
elecciones['Votos_Partido_Mas_Votado'] = elecciones[columnas_votos].max(axis=1)
elecciones
| Nombre de Comunidad | Código de Provincia | Nombre de Provincia | Código de Municipio | Nombre de Municipio | Población | Número de mesas | Total censo electoral | Total votantes | Votos válidos | ... | NATCODE | NAMEUNIT | CODNUT1 | CODNUT2 | CODNUT3 | geometry | MUNI_CODE | PROV_CODE | Partido_Mas_Votado | Votos_Partido_Mas_Votado | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Andalucía | 04 | Almería | 001 | Abla | 1.247 | 2 | 995 | 747.000 | 741 | ... | 34010404001 | Abla | ES6 | ES61 | ES611 | POLYGON ((-2.785 37.093, -2.784 37.095, -2.784... | 001 | 04 | PSOE | 294 |
| 1 | Andalucía | 04 | Almería | 002 | Abrucena | 1.221 | 2 | 1.034 | 787.000 | 781 | ... | 34010404002 | Abrucena | ES6 | ES61 | ES611 | POLYGON ((-2.890 37.092, -2.890 37.092, -2.889... | 002 | 04 | PSOE | 343 |
| 2 | Andalucía | 04 | Almería | 003 | Adra | 25.300 | 29 | 17.557 | 11.748 | 11.623 | ... | 34010404003 | Adra | ES6 | ES61 | ES611 | POLYGON ((-3.140 36.788, -3.140 36.788, -3.139... | 003 | 04 | PP | 4985 |
| 3 | Andalucía | 04 | Almería | 004 | Albanchez | 735 | 1 | 387 | 293.000 | 291 | ... | 34010404004 | Albanchez | ES6 | ES61 | ES611 | POLYGON ((-2.202 37.312, -2.202 37.312, -2.201... | 004 | 04 | PSOE | 106 |
| 4 | Andalucía | 04 | Almería | 005 | Alboloduy | 615 | 1 | 504 | 397.000 | 397 | ... | 34010404005 | Alboloduy | ES6 | ES61 | ES611 | POLYGON ((-2.713 37.078, -2.711 37.080, -2.711... | 005 | 04 | PP | 186 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 7969 | Comunitat Valenciana | 46 | Valencia / València | 262 | La Yesa | 227 | 1 | 206 | 171.000 | 169 | ... | 34104646262 | La Yesa | ES5 | ES52 | ES523 | POLYGON ((-0.982 39.840, -0.981 39.847, -0.981... | 262 | 46 | PP | 68 |
| 7970 | Comunitat Valenciana | 46 | Valencia / València | 263 | Zarra | 370 | 1 | 250 | 194.000 | 189 | ... | 34104646263 | Zarra | ES5 | ES52 | ES523 | POLYGON ((-1.214 39.123, -1.211 39.123, -1.209... | 263 | 46 | PSOE | 89 |
| 7971 | Comunitat Valenciana | 46 | Valencia / València | 902 | Gátova | 412 | 1 | 373 | 318.000 | 310 | ... | 34104646902 | Gátova | ES5 | ES52 | ES523 | POLYGON ((-0.581 39.757, -0.577 39.768, -0.577... | 902 | 46 | PSOE | 121 |
| 7972 | Comunitat Valenciana | 46 | Valencia / València | 903 | San Antonio de Benagéber | 9.874 | 10 | 6.934 | 5.454 | 5.414 | ... | 34104646903 | San Antonio de Benagéber | ES5 | ES52 | ES523 | POLYGON ((-0.522 39.576, -0.521 39.576, -0.521... | 903 | 46 | PP | 2282 |
| 7973 | Comunitat Valenciana | 46 | Valencia / València | 904 | Benicull de Xúquer | 1.102 | 1 | 894 | 688.000 | 679 | ... | 34104646904 | Benicull de Xúquer | ES5 | ES52 | ES523 | POLYGON ((-0.405 39.184, -0.405 39.184, -0.404... | 904 | 46 | PSOE | 247 |
7974 rows × 86 columns
REPRESENTACIÓN DE LOS DATOS EN UN MAPA INTERACTIVO¶
MAPA DE MARCADORES¶
En primer lugar, vamos a representar un mapa interactivo en el que se muestra un marcador en el centroide de cada municipio de la península. Dicho marcador mostrará información acerca de los resultados de las elecciones de julio de 2023. Por ejemplo, si hacemnos click en el marcador situado en el centroide del municipio de Madrid, nos mostrará la siguiente información: "Municipio: Madrid | Partido más votado: PP | Votos: 720557"
import folium
from folium.plugins import MarkerCluster
# Creamos un mapa centrado en España
m = folium.Map(location=[40.416775, -3.703790], zoom_start=6)
# Creamos marcadores
marker_cluster = MarkerCluster().add_to(m)
# Identificamos los 5 partidos más votados en toda España
top_5_partidos = elecciones.groupby('Partido_Mas_Votado')['Votos_Partido_Mas_Votado'].sum().nlargest(5).index
# Creamos un diccionario de colores para los partidos
colores_partidos = {
'PP': 'blue',
'PSOE': 'red',
'VOX': 'green',
'SUMAR': 'purple',
'ERC': 'beige',
'JxCAT - JUNTS': 'orange',
'EH Bildu': 'lightgreen',
'EAJ-PNV': 'pink',
'B.N.G.': 'lightblue',
'CCa': 'lightgray',
'U.P.N.': 'darkred',
}
# leyenda personalizada
legend_html = '<div style="position: fixed; top: 10px; right: 10px; z-index: 1000; background-color: white; padding: 10px; border: 1px solid grey; border-radius: 5px;">'
for partido, color in colores_partidos.items():
legend_html += f'<p style="margin: 0;"><span style="color: {color}; font-weight: bold;">■</span> {partido}</p>'
legend_html += '</div>'
m.get_root().html.add_child(folium.Element(legend_html))
# Iteramos sobre las filas
for idx, row in elecciones.iterrows():
municipio = row['Nombre de Municipio']
partido_mas_votado = row['Partido_Mas_Votado']
votos_partido_mas_votado = row['Votos_Partido_Mas_Votado']
# Accedemos a las coordenadas del centroide del polígono
centroid = row.geometry.centroid
centroid_lat, centroid_lon = centroid.y, centroid.x
# Creamos un marcador con pop-up
popup_text = f"Municipio: {municipio}<br>Partido más votado: {partido_mas_votado}<br>Votos: {votos_partido_mas_votado}"
folium.Marker([centroid_lat, centroid_lon], popup=popup_text, icon=folium.Icon(color=colores_partidos.get(partido_mas_votado, 'gray'))).add_to(marker_cluster)
#mapa
m